interface MyIterator {
    hasNext(): boolean;
    next(): Object | null;
}

interface Container {
    getIterator(): MyIterator;
}

class NameIterator implements MyIterator {
    private names: string[];
    private index: number = 0;
    constructor(names: string[]) {
        this.names = names;
    }
    public hasNext(): boolean {
        return this.index < this.names.length;
    }
    public next(): Object | null {
        if (this.hasNext()) {
            return this.names[this.index++];
        }
        return null;
    }
}

class NameRepository implements Container {
    public names: string[] = ["Alice", "Bob", "Charlie"];
    private NameIterator: typeof NameIterator = NameIterator;
    public getIterator(): MyIterator {
        return new this.NameIterator(this.names);
    }
}

function main() {
    const repo: NameRepository = new NameRepository();
    for (let iterator: MyIterator = repo.getIterator(); iterator.hasNext();) {
        const name: string = iterator.next() as string;
        console.log('Name: ' + name);
    }
}

main();
